<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // 一、认识内存管理
        // 1.不管什么语言，在代码的执行过程中，都是需要给它分配内存的，不同的是某些语言需要手动管理内存，某些语言需要自动管理内存
        // 2.不管是手动还是自动管理内存，都有如下的生命周期：
        // （1）分配申请需要的内存
        // （2）使用分配的内存，把数据存入内存中
        // （3）不需要使用十，释放内存
        // 3.手动管理内存的语言：C\C++
        // 4.自动管理内存的语言：JavaScript\java

        // 二、JS的内存管理
        // 1.JS会在定义变量的时候，就分配内存
        // 2.根据数据类型不同，分配内存的方式不同：
        // （1）简单数据类型分配会在执行时，直接在栈空间进行分配
        // （2）复杂数据类型分配会在堆空间中开辟一块空间存储数据，并将这块空间的地址（指针）返回值在栈空间使用变量引用

        // 三、JS的垃圾回收
        // 1.垃圾回收：因为内存空间大小有限，所以当不再需要的时候，就对其进行释放，以便腾出空间
        // 2.JS是自动管理内存，会自动释放内存空间，叫做垃圾回收（简称：GC）
        // 3.重点是需要知道如何判定当前数据已经不再需要，可以进行垃圾回收
        // 4.有两种常见的GC算法，帮助系统判断是否需要垃圾回收
        // （1）引用计数：当一个对象有一个引用指向它的时候，这个对象的引用就+1，当一个对象的引用为0时，这个对象就可以被销毁
        // 引用计数的缺点：会产生循环引用
        // let obj={
        //     friend:obj2
        // }
        // let obj2={
        //     friend:obj
        // }


        // （2）标记清除:设置一个根对象，然后垃圾回收器会定期从这个根开始，找所有从根开始有引用的对象，
        // 对于那些没有被引用到的对象，就认为是不可用对象，可以被销毁
        // 优点：可以很好的解决循环引用的问题

        // 5.js引擎比较广泛的使用标记清除算法，当然也有一些其他算法相结合


        // 四、闭包

        var eat = function () {
            var food = "鸡翅";
            return function () {
                console.log(food);
            }
        }
        var look = eat();
        look();
        look();

        // （一）闭包的定义：一个函数对其周围状态的引用捆绑在一起，这样的组合就是闭包
        // 解释：闭包让你可以在一个内层函数中访问到其外层函数的作用域
        //       在js中，每创建一个函数，闭包就会在函数创建的同时被创建出来

        // （二）广义的闭包：js中的函数都是闭包
        // （三）狭义的闭包：js中的一个函数如果访问了外层作用域的自由变量，那么这个函数就是一个闭包（重点）

        // （四）满足狭义闭包的2个必要条件：
        // 1.形成闭包环境的函数能够被外部变量引用，这样就算它外部上下文销毁，它依然存在。
        // 举例：let look=eat(); 用一个变量接受函数的返回值，返回值是函数
        // 2.在内部函数中要访问外部函数的局部变量。
        // 举例：function(){food} food就是外部函数的局部变量

        // （五）闭包的优点
        // 1.通过闭包可以让外部环境访问到函数内部的局部变量。（外部可以访问局部变量）
        // 2.通过闭包可以让局部变量持续保存下来，不随着它的上下文环境一起销毁。（延长局部变量的使用寿命）

        // （六）闭包的缺点
        // 1.可能会造成内存泄漏


        // for (let i = 1; i <= 3; i++) {
        //     setTimeout(function () {
        //         console.log(i);
        //     }, 1000);
        // }
    </script>
</body>

</html>